#
# Copyright 2012 ibiblio
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
#     http://www.apache.org/licenses/LICENSE-2.0.txt
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#

import bson

from seedbank.messaging.rabbitmq_connector import BasicMessageHandler
import seedbank.messaging.log_helper as log_helper
from seedbank.server.libtorrent_session import LibtorrentSessionQueueItem
import traceback

class ServerControlMessageHandler(BasicMessageHandler):
    def __init__(self, **kwargs):
        """
        Handles control messages received from the message queue.  This is
        treated like a mixin class, which manipulates the internals of a
        SeedbankServer object.
        """
        self._server = kwargs.get('server', None)
        self._verbose = kwargs.get('verbose', False)
        self._log = log_helper.get_logger(self.__class__.__name__)

    def handle(self, channel, method, header, body):
        if self._verbose:
            self._log.info('Received control message')

        data = None
        try:
            if body:
                decoder = bson.BSON(body)
                data = decoder.decode()
            else:
                self._log.error('Empty control message body')

            if data:
                if data.has_key('action'):
                    self._handle_action(data['action'], data)
                else:
                    self._log.warning('Missing action in control message')
        except Exception, e:
            if self._verbose:
                traceback.print_exc()
            self._log.error('Error handling message: ' + str(e))

        BasicMessageHandler.handle(self, channel, method, header, body)

    def _handle_action(self, action, data):
        if action == 'publish_stats':
            self._handle_publish_stats(bool(data['enable']))
        elif action == 'upload':
            self._handle_upload(data)
        else:
            self._log.warning('Control message received without valid action (%s)' % action)

    def _handle_publish_stats(self, enable):
        if enable:
            config = self._server._get_config()
            item = LibtorrentSessionQueueItem('publish_stats', {'enable': True, 'config': config})
        else:
            item = LibtorrentSessionQueueItem('publish_stats', {'enable': False})
        self._log.info('Received publish_stats control message (%s)' % enable)
        self._server._session_manager.send('server', item)

    def _handle_upload(self, data):
        if not data.has_key('upload_action'):
            self._log.error('Missing upload_action param in upload control message')
            return
        if not data.has_key('info_hash'):
            self._log.error('Missing info_hash param in upload control message')
            return

        upload_action = data['upload_action']
        if upload_action == 'start':
            if not data.has_key('torrent_file'):
                self._log.error('Missing torrent_file param in upload control message')
                return
            self._server._upload_manager.start(info_hash=data['info_hash'], torrent_file=data['torrent_file'], mq_out=self._server._mq_out)
        elif upload_action == 'stop':
            self._server._upload_manager.stop(info_hash=data['info_hash'])
        elif upload_action == 'cancel':
            self._server._upload_manager.cancel(info_hash=data['info_hash'])
        elif upload_action == 'delete':
            self._server._upload_manager.delete(info_hash=data['info_hash'])
        elif upload_action == 'status':
            self._server._upload_manager.status(info_hash=data['info_hash'])
        else:
            self._log.error('Invalid upload_action param in upload control message')

    def _handle_torrent(self):
        pass


